<template>
    <div class="main-content">
        <div class="control">
            <el-form :model="search" ref="searchForm" :rules="searchRules" :inline="true">
                <el-form-item>
                    <el-button type="primary" @click="handleJoin" :disabled="!category">加入项目</el-button>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="handleGit" :disabled="!category">从仓库拉取</el-button>
                </el-form-item>
                <el-form-item prop="keywords">
                    <el-input v-model="search.keywords" placeholder="搜索内容" clearable :disabled="!category" />
                </el-form-item>
                <el-form-item prop="times">
                    <el-date-picker v-model="search.times" type="datetimerange" start-placeholder="开始时间"
                        :disabled="!category" end-placeholder="结束时间" format="YYYY-MM-DD HH:mm:ss"
                        date-format="YYYY-MM-DD"
                        :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
                        time-format="hh:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" />
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="getProjects" :disabled="!category">搜索</el-button>
                    <el-button @click="resetSearch" :disabled="!category">重置</el-button>
                </el-form-item>
            </el-form>
        </div>
        <!-- <el-button type="primary" @click="$router.push({ name: 'create', params: { category } })">创建新项目</el-button> -->
        <el-table :data="projects?.data" stripe class="main-table" height="calc(100vh - 209px)">
            <el-table-column prop="name" label="项目名称" min-width="180">
                <template #default="{ row }">
                    <el-link type="primary" :underline="false" title="查看详情"
                        @click="$router.push({ name: 'detail', params: { id: row.id } })">{{ row.name }}</el-link>
                </template>
            </el-table-column>
            <el-table-column prop="path" label="目录路径" min-width="240" align="left" />
            <el-table-column prop="description" label="描述" min-width="160" align="left" />
            <el-table-column prop="created_at" label="创建时间" width="175" align="center" />
            <el-table-column label="操作" width="110" align="center" fixed="right">
                <template #default="{ row }">
                    <div class="operate">
                        <el-link type="primary" :underline="false" @click="openInFinder(row.path)" title="文件夹中打开">
                            <el-icon>
                                <Folder />
                            </el-icon>
                        </el-link>
                        <el-link type="success" :underline="false" @click="openInVsCode(row.path)" title="VSCode中打开">
                            <el-icon>
                                <VideoPlay />
                            </el-icon>
                        </el-link>
                        <el-link type="warning" :underline="false" @click="handleEdit(row)">
                            <el-icon>
                                <Edit />
                            </el-icon>
                        </el-link>
                        <el-popconfirm title="是否删除文件？" @confirm="handleDelete(row, true)"
                            @cancel="handleDelete(row, false)">
                            <template #reference>
                                <el-link type="danger" :underline="false">
                                    <el-icon>
                                        <Delete />
                                    </el-icon>
                                </el-link>
                            </template>
                        </el-popconfirm>
                    </div>
                </template>
            </el-table-column>
        </el-table>
        <el-pagination background :page-sizes="[10, 20, 50]" @change="pageChange"
            layout="total, prev, pager, next, sizes" :total="projects?.total || 0" />
    </div>
    <el-drawer v-model="drawer" direction="rtl" size="400" :before-close="resetForm" :show-close="true">
        <el-form :model="form" ref="project-form" :rules="rules" label-width="80px" :inline="false">
            <el-form-item label="名称" prop="name">
                <el-input v-model="form.name"></el-input>
            </el-form-item>
            <el-form-item label="本地路径" prop="path">
                <el-input v-model="form.path" @click="openDialog(form)" readonly />
            </el-form-item>
            <el-form-item label="描述" prop="description">
                <el-input v-model="form.description" />
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="onSubmit">保存</el-button>
                <el-button @click="resetForm">取消</el-button>
            </el-form-item>
        </el-form>
    </el-drawer>
    <el-drawer v-model="drawer_git" direction="rtl" size="400" :before-close="resetForm" :show-close="true"
        :close-on-click-modal="false">
        <el-form :model="git_form" ref="project-git" :rules="git_rules" label-width="80px" :inline="false"
            :disabled="!!shell.length">
            <el-form-item label="名称" prop="name">
                <el-input v-model="git_form.name"></el-input>
            </el-form-item>
            <el-form-item label="路径" prop="path">
                <el-input v-model="git_form.path" @click="openDialog(git_form)" readonly />
            </el-form-item>
            <el-form-item label="仓库地址" prop="git">
                <el-input v-model="git_form.git">
                    <template #prefix>
                        <span>git clone</span>
                    </template>
                </el-input>
            </el-form-item>
            <el-form-item label="描述" prop="description">
                <el-input v-model="git_form.description" />
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="onSubmitGit" :loading="loading">保存</el-button>
                <el-button @click="resetForm">取消</el-button>
            </el-form-item>
        </el-form>
        <div class="shell" v-show="!show_shell">
            <p v-for="(item, index) of shell" :key="'s' + index" :class="item.type">{{ item.value }}</p>
        </div>
    </el-drawer>
</template>

<script setup lang="ts">
import database from '@/api/database'
import { exec, openInFinder, openInVsCode } from '@/composables/useHome'
import { open } from '@tauri-apps/plugin-dialog'
import { ElMessage } from 'element-plus'
import { Folder, VideoPlay, Delete, Edit } from '@element-plus/icons-vue'
import { invoke } from '@tauri-apps/api/core'
import { path } from '@tauri-apps/api'

const checkTime = (_rule: any, value: any, callback: any) => {
    if (!value) return
    if (value instanceof Array && value.length === 2) {
        for (let index = 0; index < 2; index++) {
            if (typeof value[index] === 'string') {
                const regExp = /\d{4}-\d{2}-\d{2}\s{1}\d{2}:\d{2}:\d{2}/g
                return callback(regExp.test(value[index]) ? undefined : new Error('请选择正确的时间范围'))
            }
            return callback(new Error('请选择正确的时间范围'))
        }
    }
    callback(new Error('请选择正确的时间范围'))
}

const page = defineModel<number>('page', { required: true })
const pageSize = defineModel<number>('pageSize', { required: true })
const drawer = ref(false)
const drawer_git = ref(false)
const form = ref<Project>({ name: '', description: '', category_id: 0, path: '' })
const git_form = ref({ name: '', description: '', path: '', git: '' })
const rules = reactive({
    name: [
        { required: true, message: '请输入名称', trigger: 'blur' },
        { min: 1, max: 50, message: '长度在50个字符内', trigger: 'blur' },
    ],
    path: [
        { required: true, message: '请输入路径', trigger: 'blur' },
        { min: 1, max: 250, message: '长度在250个字符内', trigger: 'blur' },
    ],
    description: [
        { min: 1, max: 50, message: '长度在50个字符内', trigger: 'blur' },
    ]
})
const git_rules = reactive({
    name: [
        { required: true, message: '请输入名称', trigger: 'blur' },
        { min: 1, max: 50, message: '长度在50个字符内', trigger: 'blur' },
    ],
    path: [
        { required: true, message: '请输入路径', trigger: 'blur' },
        { min: 1, max: 250, message: '长度在250个字符内', trigger: 'blur' },
    ],
    description: [
        { min: 1, max: 50, message: '长度在50个字符内', trigger: 'blur' },
    ],
    git: [
        { required: true, message: '请输入仓库地址', trigger: 'blur' },
        { min: 1, max: 200, message: '长度在200个字符内', trigger: 'blur' },
    ]
})
const projectForm = useTemplateRef('project-form')
const props = defineProps<{ category: number }>()
const projects = defineModel<Paginate<Project>>('projects')
const search = ref<SearchForm>({ keywords: '', times: ['', ''] })
const searchForm = useTemplateRef('searchForm')
const projectGit = useTemplateRef('project-git')
const searchRules = reactive({
    keywords: [{ max: 20, message: '长度在20个字符内', trigger: 'blur' }],
    times: [{ validator: checkTime, trigger: 'change' }]
})
const shell = ref<{ value: string, type: 'info' | 'error' }[]>([])
const show_shell = ref(false)
const loading = ref(false)

function handleEdit(row: Project) {
    form.value = { ...row }
    drawer.value = true
}
async function handleDelete(row: Project, delFile: boolean) {
    (await database()).table('projects').where('id', row.id!).delete().then(async () => {
        if (delFile) {
            // 删除文件
            await invoke("remove", { path: row.path })
        }
        getProjects()
        ElMessage.success('操作成功')
    }).catch(err => {
        ElMessage.error(err)
    })
}
function pageChange(p: number, ps: number) {
    page.value = p
    pageSize.value = ps
    getProjects()
}
function handleJoin() {
    form.value = { name: '', description: '', category_id: 0, path: '' }
    drawer.value = true
}
function handleGit() {
    loading.value = false
    git_form.value = { name: '', description: '', path: '', git: '' }
    drawer_git.value = true
    shell.value = []
    show_shell.value = false
}
function resetForm() {
    drawer.value = false
    drawer_git.value = false
    projectForm.value?.resetFields()
    projectGit.value?.resetFields()
    show_shell.value = false
}
async function getProjects() {
    let table = (await database()).table('projects').where('category_id', props.category)
    if (search.value.keywords) {
        table = table.whereOr('name', 'like', '%' + search.value.keywords + '%')
            .whereOr('path', 'like', '%' + search.value.keywords + '%')
            .whereOr('description', 'like', '%' + search.value.keywords + '%')
    }
    if (search.value.times && search.value.times[0]) {
        table = table.whereBetween('created_at', search.value.times[0], search.value.times[1])
    }
    table.paginate<Project>(page.value, pageSize.value)
        .then(res => {
            projects.value = res
        }).catch(err => {
            ElMessage.error(err)
        })
}
function onSubmit() {
    projectForm.value?.validate(async (valid: boolean) => {
        if (valid) {
            form.value.category_id = props.category
            if (form.value?.id) {
                // 更新
                (await database()).table('projects').where('id', form.value.id).update(form.value).then(() => {
                    resetForm()
                    getProjects()
                    ElMessage.success('更新成功')
                }).catch(err => {
                    ElMessage.error(err)
                })
            } else {
                // 新增
                (await database()).table('projects').create(form.value).then(() => {
                    resetForm()
                    getProjects()
                    ElMessage.success('操作成功')
                }).catch(err => {
                    ElMessage.error(err)
                })
            }
        }
    })
}
async function onSubmitGit() {
    projectGit.value?.validate(async (valid: boolean) => {
        if (valid) {
            loading.value = true
            show_shell.value = true
            await exec('git clone ' + git_form.value.git, git_form.value.path, shell.value, async (t) => {
                if (t == 'error') {
                    ElMessage.error('操作失败')
                    loading.value = false
                    return
                }
                const data = {
                    category_id: props.category,
                    name: git_form.value.name,
                    description: git_form.value.description,
                    path: await path.join(git_form.value.path, git_form.value.git.split('/').pop()?.replace(/\.git$/, "")!),
                };
                // 新增
                (await database()).table('projects').create(data).then(() => {
                    loading.value = false
                    resetForm()
                    getProjects()
                    ElMessage.success('操作成功')
                })
            })
        }
    })
}
async function openDialog(obj: any) {
    const file = await open({ multiple: false, directory: true })
    if (file) {
        obj.path = file
    }
}
function resetSearch() {
    searchForm.value?.resetFields()
    page.value = 1
    getProjects()
}
</script>

<style lang="scss" scoped>
.main-content {
    padding-top: 20px;

    :deep(.el-dropdown) {
        display: block;
        line-height: inherit;
    }

}

.shell {
    width: 100%;
    height: 300px;
    padding: 10px;
    border-radius: 6px;
    border: 1px solid var(--el-border-color);
    background: #000;
    color: #fff;
    font-size: 12px;
    line-height: 1.8;
    overflow-y: auto;
    word-break: break-all;
    text-wrap: wrap;

    .error {
        color: var(--el-color-danger);
    }
}
</style>